﻿using Elastic.Clients.Elasticsearch;
using elasticsearch_microservice.Models;
using Microsoft.AspNetCore.Mvc;

namespace elasticsearch_microservice.Controllers
{
    /// <summary>
    /// document: 可以简单理解为一行数据
    /// </summary>
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class DocumentController : ControllerBase
    {
        private readonly ElasticsearchClient es = new();

        [HttpPost]
        public async Task<IActionResult> Insert(ProductDocument doc)
        {
            var response = await es.IndexAsync(doc.Product, ir => ir.Index(doc.IndexName));
            return Ok(response.IsValidResponse);
        }

        [HttpPost]
        public async Task<IActionResult> Update(ProductDocument doc)
        {
            var response = await es.UpdateAsync<Product, Product>
                (doc.IndexName, doc.Product.ID, ur => ur.Doc(doc.Product));

            return Ok(response.IsValidResponse);
        }

        [HttpGet]
        public async Task<IActionResult> Delete(string indexName, int id)
        {
            var response = await es.DeleteAsync(index: indexName, id);
            return Ok(response.IsValidResponse);
        }

        [HttpGet]
        public async Task<IActionResult> Select
            (string indexName = "product_index", int pageNumber = 1, int pageSize = 15)
        {
            int from = (pageNumber - 1) * pageSize;

            var response = await es.SearchAsync<Product>(sr => sr
                .Index(indexName)
                .Sort(so => so.Field(it => it.Price, fs => fs.Order(SortOrder.Desc)))
                .From(from)
                .Size(pageSize));

            if (response.IsValidResponse)
            {
                return Ok(response.Documents);
            }

            return NotFound();
        }

        [HttpGet]
        public async Task<IActionResult> SelectSearch
            (string indexName = "product_index", string keyword = "游戏手机")
        {
            var response = await es.SearchAsync<Product>(sr => sr
                .Index(indexName)
                .Query(q => q.Match(mq => mq.Field(it => it.Name).Query(keyword)))); // 支持中文分词匹配

            if (response.IsValidResponse)
            {
                return Ok(response.Documents);
            }

            return NotFound();
        }

        [HttpGet]
        public async Task<IActionResult> Detail(string indexName = "product_index", int id = 1)
        {
            var product = await es.GetAsync<Product>(id, gr => gr.Index(indexName));
            if (product.IsValidResponse)
            {
                return Ok(product.Source);
            }

            return NotFound();
        }

        [HttpGet]
        public async Task<IActionResult> AggregationsPrice(string indexName = "product_index")
        {
            var response = await es.SearchAsync<Product>(sr => sr
                .Index(indexName)
                .Aggregations(f => f
                    .Add("max_price", a => a.Max(ma => ma.Field(it => it.Price)))
                    .Add("min_price", a => a.Min(ma => ma.Field(it => it.Price)))
                    .Add("avg_price", a => a.Avg(aa => aa.Field(it => it.Price)))
                    .Add("sum_price", a => a.Sum(sa => sa.Field(it => it.Price)))
                ));

            var keyValues = new Dictionary<string, object>();

            if (response.IsValidResponse && response.Aggregations != null)
            {
                foreach (dynamic item in response.Aggregations)
                {
                    keyValues.Add(item.Key, item.Value.Value);
                }
            }

            return Ok(keyValues);
        }
    }
}
